
/*
 * Copyright 2002-2017 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*
 *版权所有2002-2017原作者。
 *
 *根据Apache许可证2.0版（“许可证”）许可；
 *除非符合许可证的规定，否则您不得使用此文件。
 *您可以在以下网址获取许可证副本
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 *除非适用法律要求或书面同意，否则软件
 *根据许可证分发是在“按原样”的基础上分发的，
 *无任何明示或暗示的保证或条件。
 *有关管理权限的特定语言，请参阅许可证
 *许可证下的限制。
 */

package org.springframework.context.support;

import java.io.IOException;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.xml.ResourceEntityResolver;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.context.ApplicationContext;
import org.springframework.core.io.Resource;
import org.springframework.lang.Nullable;

/**
 * Convenient base class for {@link org.springframework.context.ApplicationContext}
 * implementations, drawing configuration from XML documents containing bean definitions
 * understood by an {@link org.springframework.beans.factory.xml.XmlBeanDefinitionReader}.
 *
 * <p>Subclasses just have to implement the {@link #getConfigResources} and/or
 * the {@link #getConfigLocations} method. Furthermore, they might override
 * the {@link #getResourceByPath} hook to interpret relative paths in an
 * environment-specific fashion, and/or {@link #getResourcePatternResolver}
 * for extended pattern resolution.
 *
 * @author Rod Johnson
 * @author Juergen Hoeller
 * @see #getConfigResources
 * @see #getConfigLocations
 * @see org.springframework.beans.factory.xml.XmlBeanDefinitionReader
 */
/**
 *｛@link org.springframework.context.ApplicationContext｝的方便基类
 *实现，从包含bean定义的XML文档中绘制配置
 *通过{@link org.springframework.beans.factory.xml.XmlBeanDefinitionReader}理解。
 *
 *＜p＞子类只需要实现｛@link#getConfigResources｝和/或
 *｛@link#getConfigLocations｝方法。此外，它们可能会覆盖
 *｛@link#getResourceByPath｝钩子来解释
 *特定于环境的时尚，和/或｛@link#getResourcePatternResolver｝
 *用于扩展图案分辨率。
 *
 *@作者罗德·约翰逊
 *@作者Juergen Hoeller
 *@参见#getConfigResources
 *@参见#getConfigLocations
 *@参见org.springframework.beans.factory.xml.XmlBeanDefinitionReader
 */
public abstract class AbstractXmlApplicationContext extends AbstractRefreshableConfigApplicationContext {

	private boolean validating = true;


	/**
	 * Create a new AbstractXmlApplicationContext with no parent.
	 */
	/**
	 *创建一个没有父级的新AbstractXmlApplicationContext。
	 */
	public AbstractXmlApplicationContext() {
	}

	/**
	 * Create a new AbstractXmlApplicationContext with the given parent context.
	 * @param parent the parent context
	 */
	/**
	 *使用给定的父上下文创建一个新的AbstractXmlApplicationContext。
	 *@param parent父上下文
	 */
	public AbstractXmlApplicationContext(@Nullable ApplicationContext parent) {
		super(parent);
	}


	/**
	 * Set whether to use XML validation. Default is {@code true}.
	 */
	/**
	 *设置是否使用XML验证。默认值为｛@code true｝。
	 */
	public void setValidating(boolean validating) {
		this.validating = validating;
	}


	/**
	 * Loads the bean definitions via an XmlBeanDefinitionReader.
	 * @see org.springframework.beans.factory.xml.XmlBeanDefinitionReader
	 * @see #initBeanDefinitionReader
	 * @see #loadBeanDefinitions
	 */
	/**
	 *通过XmlBeanDefinitionReader加载bean定义。
	 *@参见org.springframework.beans.factory.xml.XmlBeanDefinitionReader
	 *@参见#initBeanDefinitionReader
	 *@参见#loadBeanDefinitions
	 */
	@Override
	protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
		// Create a new XmlBeanDefinitionReader for the given BeanFactory.
		// 为给定的BeanFactory创建一个新的XmlBeanDefinitionReader。
		XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

		// Configure the bean definition reader with this context's
		// 使用以下上下文配置bean定义读取器
		// resource loading environment.
		// 资源加载环境。
		beanDefinitionReader.setEnvironment(this.getEnvironment());
		beanDefinitionReader.setResourceLoader(this);
		beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

		// Allow a subclass to provide custom initialization of the reader,
		// 允许子类提供读取器的自定义初始化，
		// then proceed with actually loading the bean definitions.
		// 然后继续实际加载bean定义。
		initBeanDefinitionReader(beanDefinitionReader);
		loadBeanDefinitions(beanDefinitionReader);
	}

	/**
	 * Initialize the bean definition reader used for loading the bean
	 * definitions of this context. Default implementation is empty.
	 * <p>Can be overridden in subclasses, e.g. for turning off XML validation
	 * or using a different XmlBeanDefinitionParser implementation.
	 * @param reader the bean definition reader used by this context
	 * @see org.springframework.beans.factory.xml.XmlBeanDefinitionReader#setDocumentReaderClass
	 */
	/**
	 *初始化用于加载bean的bean定义读取器
	 *本上下文的定义。默认实现为空。
	 *＜p＞可以在子类中重写，例如用于关闭XML验证
	 *或者使用不同的XmlBeanDefinitionParser实现。
	 *@param reader此上下文使用的bean定义读取器
	 *@参见org.springframework.beans.factory.xml.XmlBeanDefinitionReader#setDocumentReaderClass
	 */
	protected void initBeanDefinitionReader(XmlBeanDefinitionReader reader) {
		reader.setValidating(this.validating);
	}

	/**
	 * Load the bean definitions with the given XmlBeanDefinitionReader.
	 * <p>The lifecycle of the bean factory is handled by the {@link #refreshBeanFactory}
	 * method; hence this method is just supposed to load and/or register bean definitions.
	 * @param reader the XmlBeanDefinitionReader to use
	 * @throws BeansException in case of bean registration errors
	 * @throws IOException if the required XML document isn't found
	 * @see #refreshBeanFactory
	 * @see #getConfigLocations
	 * @see #getResources
	 * @see #getResourcePatternResolver
	 */
	/**
	 *使用给定的XmlBeanDefinitionReader加载bean定义。
	 *＜p＞bean工厂的生命周期由｛@link#refreshBeanFactory｝处理
	 *方法；因此，该方法只是用来加载和/或注册bean定义。
	 *@param reader要使用的XmlBeanDefinitionReader
	 *在bean注册错误的情况下@throws BeansException
	 *如果找不到所需的XML文档，则@throws IOException
	 *@见#refreshBeanFactory
	 *@参见#getConfigLocations
	 *@参见#getResources
	 *@参见#getResourcePatternResolver
	 */
	protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
		Resource[] configResources = getConfigResources();
		if (configResources != null) {
			reader.loadBeanDefinitions(configResources);
		}
		String[] configLocations = getConfigLocations();
		if (configLocations != null) {
			reader.loadBeanDefinitions(configLocations);
		}
	}

	/**
	 * Return an array of Resource objects, referring to the XML bean definition
	 * files that this context should be built with.
	 * <p>The default implementation returns {@code null}. Subclasses can override
	 * this to provide pre-built Resource objects rather than location Strings.
	 * @return an array of Resource objects, or {@code null} if none
	 * @see #getConfigLocations()
	 */
	/**
	 *返回一个Resource对象数组，引用XMLbean定义
	 *该上下文应该使用的文件。
	 *＜p＞默认实现返回｛@code null｝。子类可以重写
	 *这是为了提供预先构建的资源对象，而不是位置字符串。
	 *@返回一个Resource对象数组，如果没有，则返回｛@code null｝
	 *@参见#getConfigLocations（）
	 */
	@Nullable
	protected Resource[] getConfigResources() {
		return null;
	}

}
